package com.art.museumbackend.aspect;

import com.art.museumbackend.annotation.Log;
import com.art.museumbackend.entity.SystemLog;
import com.art.museumbackend.service.SystemLogService;
import com.art.museumbackend.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Map;

@Aspect
@Component
public class LogAspect {

    @Autowired
    private SystemLogService systemLogService;

    @Around("@annotation(log)")
    public Object around(ProceedingJoinPoint point, Log log) throws Throwable {
        Object result = null;
        long beginTime = System.currentTimeMillis();
        
        try {
            // 执行方法
            result = point.proceed();
            // 执行时长(毫秒)
            long time = System.currentTimeMillis() - beginTime;
            // 保存日志
            saveLog(point, log, time, result, null);
        } catch (Exception e) {
            // 保存异常日志
            saveLog(point, log, System.currentTimeMillis() - beginTime, null, e);
            throw e;
        }
        
        return result;
    }

    private void saveLog(ProceedingJoinPoint joinPoint, Log log, long time, Object result, Exception e) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        
        // 获取当前登录用户
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = map != null ? (String) map.get("username") : "unknown";

        // 获取请求信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 构建日志对象
        SystemLog systemLog = SystemLog.builder()
                .username(username)
                .operation(log.value())
                .method(signature.getDeclaringTypeName() + "." + signature.getName())
                .params(String.valueOf(joinPoint.getArgs()))
                .ip(request.getRemoteAddr())
                .status(e == null ? "success" : "fail")
                .errorMsg(e != null ? e.getMessage() : null)
                .logType(log.type())
                .createTime(LocalDateTime.now())
                .build();

        // 保存日志
        systemLogService.save(systemLog);
    }
} 